package com.cn.service.impl;

import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import org.redisson.api.RLock;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import redis.clients.jedis.JedisPool;
import ch.qos.logback.classic.Logger;

import com.cn.constant.ProConstant;
import com.cn.dao.OrderMapper;
import com.cn.domain.OrderEntity;
import com.cn.domain.ProductEntity;
import com.cn.service.DistributedLocker;
import com.cn.service.OrderService;
import com.cn.service.ProductService;
import com.cn.service.RedisLockService;
@Service(value="orderService")
public class OrderServiceImpl implements OrderService {
	protected static Logger logger=(Logger) LoggerFactory.getLogger(OrderServiceImpl .class);  
	@Autowired  
    private OrderMapper orderMapper;
	
 
	
	@Autowired
	private ProductService productService;
	
    @Autowired
    private RedisLockService redisLockService;
    @Autowired
	private DistributedLocker distributedLocker;
	@Autowired  
    private RedisTemplate redisTemplate;
    @Autowired
   private JedisPool jedisPool;
	
	@Async("myTaskAsyncPool")
	public int insertOrder(OrderEntity orderEntity) {
		// TODO Auto-generated method stub
		return orderMapper.insertOrder(orderEntity);
	}

	public List<OrderEntity> findOrderEntityByWhere(OrderEntity orderEntity) {
		// TODO Auto-generated method stub
		return orderMapper.findOrderEntityByWhere(orderEntity);
	}

	public int cancleOrderEntity(OrderEntity orderEntity) {
		// TODO Auto-generated method stub
		return orderMapper.cancleOrderEntity(orderEntity);
	}
	@Transactional(isolation = Isolation.READ_COMMITTED )
	public int secondKill(OrderEntity orderEntity){
		if(orderEntity == null ){
			orderEntity = new OrderEntity();
		}
	 
		ProductEntity product = new ProductEntity();
		product.setProductId(orderEntity.getProductId());
	 
		ProductEntity result = this.productService.queryProductForUpdate(product);
		//���пۼ��������ɶ���
		if(result.getProductNum() -orderEntity.getNum() < 0){
			return 0;
		}
		product.setProductNum(result.getProductNum() -1);
		
		   insertOrder(orderEntity);
		 
		   return this.productService.updateProductEntity(product);
	}
	@Transactional 
	public int insertBatchOrder(List<OrderEntity> orderList) {
		// TODO Auto-generated method stub
		return this.orderMapper.insertBatchOrder(orderList);
	}
	@Transactional 
	public int secondKillRedis(OrderEntity orderEntity) {
		// TODO Auto-generated method stub
		String productNumLock="productNum"+orderEntity.getProductId();
		try{
		 
		 
				 
			 
				 ProductEntity product = new ProductEntity();
				 product.setProductId(orderEntity.getProductId());
				 List<ProductEntity> list = this.productService.findProductEntityByWhere(product);
				 ProductEntity one =list.get(0);
				 int left = one.getProductNum()-orderEntity.getNum();
				 
				 if( left >= 0){
					 String queue = ProConstant.QUEUE+orderEntity.getProductId();
					long r= redisTemplate.opsForList().rightPush(queue, orderEntity);
					System.out.println("productNum r"+left) ;
					if(r <0){
						 throw new Exception(" redis error");
					 }
					 product.setProductNum(left);
					 product.setModifyTime(new Date());
				    this.productService.updateProductEntity(product);
				 }
		   
		}catch(Exception e){
			e.printStackTrace();
			return 0;
		} 
		 
		 
		 return 1;
		 
	}
	
}
